﻿using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using Castle.Core.Interceptor;

namespace WcfPOXCommunication
{
    internal class ServiceInvokerProxy : IInterceptor
    {
        private IRequestProcessor RequestProcessor { get; set; }

        private IResponseProcessor ResponseProcessor { get; set; }

        public ServiceInvokerProxy()
        {
            RequestProcessor = new RequestProcessor();
            ResponseProcessor = new ResponseProcessor();
        }
        
        public void Intercept(IInvocation invocation)
        {
            if (invocation.Method.IsSpecialName)
            {
                return;
            }
            //encode request
            var serviceRequest = RequestProcessor.Encode(invocation);

            // invoke
            var msg = Message.CreateMessage(MessageVersion.Soap12WSAddressing10,
                                            "HandleMessage", serviceRequest);

            var factory = new ChannelFactory<IServiceFacade>(
                new WSHttpBinding(SecurityMode.None), 
                "http://trentcioranpc:54321/ServiceFacade");
            var proxy = factory.CreateChannel();
            var response = proxy.HandleMessage(msg);
            var serviceResponse = response.GetBody<ServiceResponse>();

            var decodedResponse = ResponseProcessor.Decode(invocation, serviceResponse);
            // process response
            if (serviceResponse.Success)
            {
                invocation.ReturnValue = decodedResponse.Result;
            }
            else
            {
                // process error
                var ex = (Exception)Activator.CreateInstance(decodedResponse.FaultType,
                    new object[] { decodedResponse.ErrorMessage });
                throw ex;
            }
        }
    }
}